﻿#region Using

using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;

using Common.Properties;

#endregion

namespace Common.Base
{
    [DebuggerDisplay("{X}, {Y}")]
    public sealed class Position : INotifyPropertyChanged
    {
        private int x;

        private int y;

        public Position()
        {
            this.x = 0;
            this.y = 0;
        }

        public Position(int x, int y)
        {
            this.X = x;
            this.Y = y;
        }

        public Position(Position pos)
        {
            this.X = pos.x;
            this.Y = pos.y;
        }

        public int X
        {
            get
            {
                return this.x;
            }

            set
            {
                if (value == this.x)
                {
                    return;
                }

                this.x = value;
                this.OnPropertyChanged();
            }
        }

        public int Y
        {
            get
            {
                return this.y;
            }

            set
            {
                if (value == this.y)
                {
                    return;
                }

                this.y = value;
                this.OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public static Position operator -(Position pos, int op)
        {
            return new Position(pos.X - op, pos.Y - op);
        }

        public static Position operator -(Position pos)
        {
            return new Position(-pos.X, -pos.Y);
        }

        public static Position operator +(Position pos, int op)
        {
            return new Position(pos.X + op, pos.Y + op);
        }

        public static Position operator -(Position pos, Position op)
        {
            return new Position(pos.x - op.x, pos.y - op.y);
        }

        public static Position operator +(Position pos, Position op)
        {
            return new Position(pos.x + op.x, pos.y + op.y);
        }

        public override string ToString()
        {
            return string.Format("X:{0} Y:{1}", this.X, this.Y);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return (this.x * 397) ^ this.y;
            }
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }

            var pos = obj as Position;
            if (pos == null)
            {
                return false;
            }

            return this.x == pos.x && this.y == pos.y;
        }

        [NotifyPropertyChangedInvocator]
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}